#include "WriteExcel_1.0.hpp"

#include <fstream>
#include <OpenXLSX.hpp>
#include <sstream>
#include <filesystem>

#include "GcovManager.hpp"
// TODO 查分不同的版本的模板excel
namespace
{
    bool isHaveSameFile(std::string fileName);
    void copyFile(std::shared_ptr<std::ifstream> demoExcelFil, std::string currentPath, std::string fileName);
} // namespace

void wxlsx::write_xlsx_1_0(const std::string demoFileName, const std::string projectPath, std::shared_ptr<wxlsx::ExcelUtInfoList> infoList)
{
    if (demoFileName.empty() || projectPath.empty())
    {
        LOG("demo or current path is empty");
        return;
    }

    LOG("demo file name: %s", demoFileName.c_str());
    LOG("current path: %s", projectPath.c_str());

    std::string currentPath = projectPath.substr(0, projectPath.find_last_of("\\"));

    std::shared_ptr<std::ifstream> demoExcelFile(new std::ifstream(demoFileName, std::ios::binary), [](std::ifstream *data) -> void
                                                 {
                                                    if(data != nullptr)
                                                    {
                                                        data->close();
                                                        delete data;
                                                    } });
    if (demoExcelFile->is_open() == false)
    {
        LOG("can not open file: %s", demoFileName.c_str());
        return;
    }

    infoList->foreach ([&](std::shared_ptr<wxlsx::ExcelUtInfo> info) -> void
                       {
                            if(isHaveSameFile(currentPath + "/UT_Result_" + info->outputFileName + ".xlsx"))
                            {
                                LOG("waring: have same file.");
                                return;
                            }
                            copyFile(demoExcelFile, currentPath, info->outputFileName); 
                            OpenXLSX::XLDocument doc;
                            LOG("open file: %s", (currentPath + "/UT_Result_" + info->outputFileName + ".xlsx").c_str());
                            doc.open(currentPath + "/UT_Result_" + info->outputFileName + ".xlsx");

                            OpenXLSX::XLWorksheet sheet1 = doc.workbook().worksheet("Sheet1");

                            /**
                             * 目前不清楚如何操作别名单元格，只能放弃别名了
                             */
                            sheet1.cell("D4") = info->methodName;
                            sheet1.cell("D5") = info->linesExecuted/100.0;
                            sheet1.cell("D6") = info->branchesExecuted/100.0;
                            sheet1.cell("D7") = info->funcInCount;
                            sheet1.cell("D8") = info->funcOutCount;
                            sheet1.cell("D9") = info->caseNumber;

                            info->xmlCaseInfoList.foreach ([&](std::shared_ptr<gcov::XmlCaseInfo> info) -> void{
                                int line = 12 + info->caseID;
                                sheet1.cell("B" + std::to_string(line)) = info->caseID;
                                sheet1.cell("D" + std::to_string(line)) = info->useOnStatus;
                                sheet1.cell("F" + std::to_string(line)) = info->expected;
                                sheet1.cell("H" + std::to_string(line)) = info->actual;
                                sheet1.cell("J" + std::to_string(line)) = info->name;
                                sheet1.cell("K" + std::to_string(line)) = info->time;
                                if(info->expected.compare(info->actual) == 0)
                                    sheet1.cell("L" + std::to_string(line)) = "OK";
                                else
                                    sheet1.cell("L" + std::to_string(line)) = "NG";
                            });

                            doc.save();
                            doc.close(); });
}

namespace
{
    bool isHaveSameFile(std::string fileName)
    {
        return std::filesystem::exists(fileName);
    }

    void copyFile(std::shared_ptr<std::ifstream> demoExcelFil, std::string currentPath, std::string fileName)
    {
        std::shared_ptr<std::ofstream> outFile(new std::ofstream(currentPath + "/UT_Result_" + fileName + ".xlsx", std::ios::binary), [](std::ofstream *data) -> void
                                               {
                                                    if (data != nullptr)
                                                    {
                                                        data->close();
                                                        delete data;
                                                    } });

        if (outFile->is_open() == false)
        {
            LOG("can not open file: %s", (currentPath + "/" + fileName).c_str());
            return;
        }

        (*outFile) << demoExcelFil->rdbuf();

        bool succ = demoExcelFil->good();
        if (succ == false)
        {
            LOG("copy file error: %s", (currentPath + "/" + fileName).c_str());
            return;
        }
    }
} // namespace
